﻿using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web;

namespace Framework
{
    public class SimplePaging
    {
        private readonly HttpRequest _request;
        private string _queryString;

        public SimplePaging()
        {
            First = "首页";
            Previous = "上一页";
            Next = "下一页";
            Last = "末页";
            PageParams = "page";
            RowsParams = "rows";
            _request = HttpContext.Current.Request;
            CurrentUrl = _request.Path;
            _queryString = _request.ServerVariables["Query_String"];
            if (_queryString.StartsWith("?"))
                _queryString = _queryString.TrimStart('?');
            Css = "pages";
            MaxShow = 5;
        }

        public string First { get; set; }
        public string Previous { get; set; }
        public string Next { get; set; }
        public string Last { get; set; }
        public string PageUrl { get; set; }
        public string PageParams { get; set; }
        public int Total { get; set; }
        public int MaxShow { get; set; }
        public int Rows { get; set; }
        public int Index { get; set; }
        public string Css { get; set; }
        public string RowsParams { get; set; }
        public string CurrentUrl { get; set; }
        public int PageCount { get; set; }


        public string Building(int total, int rows, int index)
        {
            Total = total;
            Index = index;
            Rows = rows;
            return Building();
        }

        public string Building()
        {
            int total = Total;
            int index = Index;
            int rows = Rows;
            int pageSize = total / rows;
            int showCount = MaxShow / 2;
            if (total % rows > 0)
                pageSize += 1;
            var html = new StringBuilder();
            html.AppendFormat("<div class=\"{0}\">", Css);
            if (total < rows)
            {
            }
            /*第一步*/
            if (index > 1)
            {
                html.AppendFormat("<a href=\"{0}\">{1}</a>", GetHrefString(1), First);
                html.AppendFormat("<a href=\"{0}\">{1}</a>", GetHrefString(index - 1), Previous);
            }
            else
            {
                html.AppendFormat("<a class=\"disable\">{0}</a>", First);
                html.AppendFormat("<a class=\"disable\">{0}</a>", Previous);
            }


            int startIndex = index - showCount;
            int endIndex = index + showCount;
            if (startIndex < 1)
            {
                endIndex = endIndex - startIndex + 1;
                startIndex = 1;
            }

            if (endIndex > pageSize)
            {
                startIndex = startIndex - (endIndex - pageSize);
                endIndex = pageSize;
                if (startIndex < 1)
                    startIndex = 1;
            }
            for (int i = startIndex; i <= endIndex; i++)
            {
                if (i == index)
                {
                    html.AppendFormat("<a href=\"{0}\" class=\"current\">{1}</a>", GetHrefString(i), i);
                    continue;
                }
                html.AppendFormat("<a href=\"{0}\">{1}</a>", GetHrefString(i), i);
            }
            /*第一步*/
            if (index < pageSize)
            {
                html.AppendFormat("<a href=\"{0}\">{1}</a>", GetHrefString(index + 1), Next);
                html.AppendFormat("<a href=\"{0}\">{1}</a>", GetHrefString(pageSize), Last);
            }
            else
            {
                html.AppendFormat("<a class=\"disable\">{0}</a>", Next);
                html.AppendFormat("<a class=\"disable\">{0}</a>", Last);
            }
            html.Append("</div>");
            return html.ToString();
        }

        /// <summary>
        /// add paging parameter and value to the current url or change parameter value if it already exists when using url paging mode
        /// </summary>
        /// <param name="sk">name of the url parameter to be added</param>
        /// <param name="sv">value of the url paramter to be added</param>
        /// <returns>href string for the navigattion button</returns>
        private string BuildUrlString(string sk, string sv)
        {
            var ubuilder = new StringBuilder(80);
            bool keyFound = false;
            int num = (_queryString != null) ? _queryString.Length : 0;
            if (_queryString == null)
                _queryString = string.Empty;
            for (int i = 0; i < num; i++)
            {
                int startIndex = i;
                int num4 = -1;
                while (i < num)
                {
                    char ch = _queryString[i];
                    if (ch == '=')
                    {
                        if (num4 < 0)
                        {
                            num4 = i;
                        }
                    }
                    else if (ch == '&')
                    {
                        break;
                    }
                    i++;
                }
                string skey = null;
                string svalue;
                if (num4 >= 0)
                {
                    skey = _queryString.Substring(startIndex, num4 - startIndex);
                    svalue = _queryString.Substring(num4 + 1, (i - num4) - 1);
                }
                else
                {
                    svalue = _queryString.Substring(startIndex, i - startIndex);
                }
                ubuilder.Append(skey).Append("=");
                if (skey == sk)
                {
                    keyFound = true;
                    ubuilder.Append(sv);
                }
                else
                {
                    ubuilder.Append(svalue);
                }
                ubuilder.Append("&amp;");
            }
            if (!keyFound)
                ubuilder.Append(sk).Append("=").Append(sv);
            ubuilder.Insert(0, "?").Insert(0, Path.GetFileName(CurrentUrl));
            string lnk = ubuilder.ToString();
            if (lnk.EndsWith("&amp;"))
                return lnk.Substring(0, lnk.Length - 5);
            return lnk;
        }

        private string GetHrefString(int pageIndex)
        {
            int urlPageIndex = pageIndex;
            return BuildUrlString(PageParams, urlPageIndex.ToString(CultureInfo.InvariantCulture));
        }

        /// <summary>
        /// Convert raw query string to NameValueCollection
        /// </summary>
        /// <param name="s">raw query string</param>
        private static NameValueCollection ConvertQueryStringToCollection(string s)
        {
            var prms = new NameValueCollection();
            int num = (s != null) ? s.Length : 0;
            for (int i = 0; i < num; i++)
            {
                int startIndex = i;
                int num4 = -1;
                while (i < num)
                {
                    char ch = s[i];
                    if (ch == '=')
                    {
                        if (num4 < 0)
                        {
                            num4 = i;
                        }
                    }
                    else if (ch == '&')
                    {
                        break;
                    }
                    i++;
                }
                string skey = null;
                string svalue;
                if (num4 >= 0)
                {
                    skey = s.Substring(startIndex, num4 - startIndex);
                    svalue = s.Substring(num4 + 1, (i - num4) - 1);
                }
                else
                {
                    svalue = s.Substring(startIndex, i - startIndex);
                }
                prms.Add(skey, svalue);
                if ((i == (num - 1)) && (s[i] == '&'))
                {
                    prms.Add(null, string.Empty);
                }
            }
            return prms;
        }
    }
}